﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
using System.Text;

namespace Grishko.Tools
{

    /// <summary>
    /// Инструменты по обработке командной строки
    /// </summary>
    public class QueryStringTools
    {
        public static string qReturnUrl = "ReturnUrlParam";
        public static string qReturnUrlSplitter_Q = "^";
        public static string qReturnUrlSplitter_And = "$";

        public class Comparer : IEqualityComparer<qStringParam>
        {
            #region IEqualityComparer<qStringParam> Members

            public bool Equals(qStringParam x, qStringParam y)
            {
                if (x.Param.ToUpper().Equals(y.Param.ToUpper()))
                    return true;
                else
                    return false;
            }

            public int GetHashCode(qStringParam obj)
            {

                Func<string, Int32> f = delegate(string s)
                {
                    Int32 res = 0;
                    foreach (char i in s.ToCharArray())
                    {
                        res = res + (int)i;

                    }
                    return res;
                };
                qStringParam v = (qStringParam)obj;
                return f(v.Param);
            }

            #endregion
        }

        public class qStringParam
        {
            public string Param { get; set; }
            public string Value { get; set; }
        }

        public QueryStringTools()
        {

        }

        /// <summary>
        ///Пакует текущий url в параметр ReturnUrl 
        /// </summary>
        /// <returns>@ReturnUrl=параметр=значение_параметр=значение  </returns>
        public static string GetReturnUrlParam()
        {
            Uri url = HttpContext.Current.Request.Url;
            string s = url.PathAndQuery.Replace("?", qReturnUrlSplitter_Q);            
            s = s.Replace("&", qReturnUrlSplitter_And);
            return (s);

        }
        public static string CurrentUrl
        {
            get
            {
                Uri url = HttpContext.Current.Request.Url;
                return url.PathAndQuery;
            }
        }
      
        /// <summary>
        /// Передергивает страницу используя пришедшие параметры, 
        /// если в запросе были параметры - они подменяются
        /// </summary>
        /// <param name="Params">Пары  параметр значение</param>
        public static void RefreshPage(HashSet<qStringParam> Params)
        {
            Uri url = HttpContext.Current.Request.Url;
            HashSet<qStringParam> hs1 = QueryStringTools.StringToHashSet(url.Query);
            Params.SymmetricExceptWith(hs1);

            string sUrl = url.LocalPath + (Params.Count > 0 ? "?" + HashSetToString(Params) : string.Empty);
            HttpContext.Current.Response.Redirect(sUrl);

        }

        /// <summary>
        /// Передергивает страницу используя пришедшие параметры, 
        /// если в запросе были параметры - они подменяются
        /// </summary>
        /// <param name="Params">Пары  параметр значение</param>
        public static void RefreshPage(string sParams)
        {
            Uri url = HttpContext.Current.Request.Url;
            sParams = GetModifyParamsRequest(sParams,url.Query.Replace("?", string.Empty));
            string sUrl = url.LocalPath + (sParams.Length > 0 ? "?" + sParams : string.Empty);
            HttpContext.Current.Response.Redirect(sUrl);
        }

        /// <summary>
        ///  Передергивает страницу используя пришедшие параметры, 
        /// если в запросе были параметры - они подменяются
        /// </summary>
        /// <param name="sParams"></param>
        /// <param name="DeletedParams"></param>
        public static void RefreshPage(string sParams, string[] DeleteParams)
        {
            Uri url = HttpContext.Current.Request.Url;

            HashSet<qStringParam> hs= QueryStringTools.StringToHashSet(url.Query.Replace("?", string.Empty));
            
            hs.RemoveWhere (delegate (qStringParam obj)
                            {
                                for (int i = 0; i < DeleteParams.Length; i++)
                                    if ((obj.Param.ToUpper() == DeleteParams[i].ToUpper()))
                                        return true;

                                 return false;
                                
                             });


            sParams = GetModifyParamsRequest(sParams, HashSetToString(hs));
            string sUrl = url.LocalPath + (sParams.Length > 0 ? "?" + sParams : string.Empty);
            HttpContext.Current.Response.Redirect(sUrl);
        }

        //private static bool isEven(qStringParam i)
        //{
        //    return true;
        //}

        /// <summary>
        /// Микисровать два множества параметров 
        /// </summary>
        /// <param name="sParams"></param>
        /// <returns></returns>
        public static string GetModifyParamsRequest(string sFirst, string sSecond)
        {
            HashSet<qStringParam> First = QueryStringTools.StringToHashSet(sFirst);
            HashSet<qStringParam> Second = QueryStringTools.StringToHashSet(sSecond);
            First.UnionWith(Second);
            return HashSetToString(First);                        
        }
        /// <summary>
        /// Передернуть  страницу с новым набором параметров
        /// </summary>
        /// <param name="sParams"></param>
        public static void RefreshPageWitchNewParams(string sParams)
        {
            Uri url = HttpContext.Current.Request.Url;
            HashSet<qStringParam> Params = QueryStringTools.StringToHashSet(sParams);
            string sUrl = url.LocalPath + (Params.Count > 0 ? "?" + HashSetToString(Params) : string.Empty);
            HttpContext.Current.Response.Redirect(sUrl);
        }

        /// <summary>
        /// Передернуть  используя параметр ReturnUrl
        /// </summary>
        /// <param name="sParams"></param>
        public static void RefreshPageWitchReturnUrl()
        {
            Uri url = HttpContext.Current.Request.Url;
            string s = GetParamValue(qReturnUrl);
            s = s.Replace(qReturnUrlSplitter_And, "&").Replace(qReturnUrlSplitter_Q, "?");            
            HttpContext.Current.Response.Redirect(s);
        }

        public static void RefreshPage(string PageUrl, string sParams)
        {
            Uri url = HttpContext.Current.Request.Url;
            HashSet<qStringParam> Params = QueryStringTools.StringToHashSet(sParams);
            string sUrl = PageUrl + (Params.Count > 0 ? "?" + HashSetToString(Params) : string.Empty);
            HttpContext.Current.Response.Redirect(sUrl);
        }



        //перегоняет строку формата queryString в коллекцию
        public static HashSet<qStringParam> StringToHashSet(String QueryString)
        {
            //QueryString = QueryString.Replace("?", string.Empty);
            //QueryString = QueryString.Replace("%40", "@");

            QueryStringTools.Comparer cmp = new Comparer();
            HashSet<qStringParam> result = new HashSet<qStringParam>(cmp);
            string[] s = QueryString.Split("&".ToCharArray()[0]);
            foreach (string i in s)
            {
                int j = i.IndexOf("=");

                result.Add(new qStringParam()
                                {
                                    Param = i.Substring(0, j),
                                    Value = i.Substring(j + 1)
                                });

            }
            return result;
        }

        //перегоняет  коллекцию в  строку формата queryString 
        public static string HashSetToString(HashSet<qStringParam> Params)
        {
            StringBuilder sb = new StringBuilder();
            qStringParam[] arr = Params.ToArray<qStringParam>();
            for (int i = 0; i < Params.Count; i++)
            {
                sb.Append(i > 0 ? "&" : string.Empty);
                sb.Append(arr[i].Param + "=" + arr[i].Value);
            }
            return sb.ToString();
        }

        
        public static string GetParamValue(string ParamID)
        {
            return HttpContext.Current.Request.QueryString[ParamID];
        }
    }
}
